﻿using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace CsharpTool.SignalRServer
{
    /// <summary>
    /// SignalRHub
    /// </summary>
    public class SignalRHub<TClient, TReceiveData> : Hub<TClient>, ISignalRHub<TClient, TReceiveData> where TClient : class, ISignalRHubClient
    {
        protected readonly ILogger<SignalRHub<TClient, TReceiveData>> Logger;
        protected readonly IMessageReceive<TReceiveData>? MessageReceive;
        protected readonly IServiceProvider ServiceProvider;

        /// <summary>
        /// ctor
        /// </summary>
        public SignalRHub(IServiceProvider serviceProvider, ILogger<SignalRHub<TClient, TReceiveData>> logger)
        {
            ServiceProvider = serviceProvider;
            MessageReceive = ServiceProvider.GetService<IMessageReceive<TReceiveData>>();
            Logger = logger;
        }


        public async override Task OnConnectedAsync()
        {
            if (MessageReceive != null)
            {
                try
                {
                    await MessageReceive.ConnectionChangeAsync(new ConnectionInfo()
                    {
                        ConnectionId = Context.ConnectionId,
                        User = Context.User,
                        IsConnected = true
                    });
                }
                catch (Exception e)
                {
                    Logger?.LogError(e, "SignalR -> [{id}] IMessageReceive.ConnectionChangeAsync数据处理异常", Context.ConnectionId);
                }
            }

            await base.OnConnectedAsync();
        }

#pragma warning disable CS8765 // 参数类型的为 Null 性与重写成员不匹配(可能是由于为 Null 性特性)。
        public async override Task OnDisconnectedAsync(Exception exception)
#pragma warning restore CS8765 // 参数类型的为 Null 性与重写成员不匹配(可能是由于为 Null 性特性)。
        {
            if (MessageReceive != null)
            {
                try
                {
                    await MessageReceive.ConnectionChangeAsync(new ConnectionInfo()
                    {
                        ConnectionId = Context.ConnectionId,
                        User = Context.User,
                        IsConnected = false
                    });
                }
                catch (Exception e)
                {
                    Logger?.LogError(e, "SignalR -> [{id}] IMessageReceive.ConnectionChangeAsync数据处理异常", Context.ConnectionId);
                }
            }

            await base.OnDisconnectedAsync(exception);
        }

        /// <summary>
        /// 客户端发送消息时调用
        /// </summary>
        [HubMethodName("SendMsg")]
        public virtual async Task SendMsgAsync(TReceiveData msg)
        {
            if (MessageReceive != null)
            {
                try
                {
                    await MessageReceive.ReceiveMsgAsync(Context.ConnectionId, msg);
                }
                catch (Exception e)
                {
                    Logger?.LogError(e, "SignalR -> [{id}] IMessageReceive.ReceiveMsgAsync数据处理异常", Context.ConnectionId);
                }
            }
        }
    }

    /// <summary>
    /// SignalRHub
    /// </summary>
    public class SignalRHub : SignalRHub<ISignalRHubClient, MsgInfo>
    {
        /// <summary>
        /// ctor
        /// </summary>
        public SignalRHub(IServiceProvider serviceProvider, ILogger<SignalRHub> logger) : base(serviceProvider, logger)
        {
        }
    }
}